/**
@file
@brief Provide universal functions of H-Bridge.
@details 
    The H-Bridge control is based on the following truth table(TMI8260SP):
     _________________________
    | InA | InB | OutA | OutB |
    |=====|=====|======|======|
    |  H  |  L  |  H   |  L   |
    |-----|-----|------|------|
    |  L  |  H  |  L   |  H   |
    |-----|-----|------|------|
    |  H  |  H  |  L   |  L   |
    |-----|-----|------|------|
    |  L  |  L  | Open | Open |
    |_____|_____|______|______|
*/

#ifndef HBRIDGE_H__
#define HBRIDGE_H__

#include "board.h"


/** @brief Information about the hardware to drive an H-Bridge.
*/
typedef struct {
//    const TIM_TypeDef *                 AvdTim;         /**< Advanced TIMx*/
//    const uint16_t                      PwmChannel;  /**< TIM_Channel_1/2/3/4*/
    GPIO_TypeDef * const                GpioPort_InA;   
    GPIO_TypeDef * const                GpioPort_InB;
    const uint16_t                      Pin_InA;
    const uint16_t                      Pin_InB;
} HBridgeHW_TypeDef;


/**@brief Define which configuration of output level cause motor to spin forward.   */
typedef enum {
    HB_DirMode_AHBLasForward = 0,  /**< OutA high, OutB low makes the motor run forward.*/
    HB_DirMode_ALBHasForward = 1,  /**< OutA low, OutB high makes the motor run forward.*/
} HBridge_DirMode_TypeDef;


/**@brief The direction to be choose.*/
typedef enum {
    HB_Dir_Forward = 0,  /**< Motor runs forward.*/
    HB_Dir_Backward = 1, /**< Motor runs backward. */
} HBridge_Dir_TypeDef;


typedef enum {
    HB_State_Run = 0,       /**< Forward or backward */
    HB_State_Brake = 1,     /**< Stops quickly */
    HB_State_Coast = 2,     /**< Stops slowly */
} HBridge_State_TypeDef;


/**@brief Parameters to be transported.*/
typedef struct {
    uint16_t Dir:1;
    uint16_t DirMode:1;
    uint16_t rsvd1:1;
    uint16_t rsvd2:1;
    
    uint16_t State:3;
    uint16_t rsvd3:9;
} HBridgeParam_TypeDef;


typedef volatile struct {
    HBridgeHW_TypeDef       Hw;
    HBridgeParam_TypeDef    Param;
    bool ParamChanged;
} HBridge_TypeDef;


/* ===== ===== ===== Exported Handles ===== ===== =====*/
extern HBridge_TypeDef hstHBdg_1;
extern HBridge_TypeDef hstHBdg_2;
extern HBridge_TypeDef hstHBdg_3;
extern HBridge_TypeDef hstHBdg_4;

/* ===== ===== ===== Exported Functions ===== ===== =====*/
void HBridge_Init(void);
void HBridge_SetPwmDuty(volatile HBridge_TypeDef* hb, uint16_t duty);
void HBridge_Update(volatile HBridge_TypeDef* hb);


#endif  // HBRIDGE_H__
